package com.fengniu.ejb.business.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import org.jboss.ejb3.annotation.LocalBinding;
import org.jboss.ejb3.annotation.RemoteBinding;

import com.fengniu.ejb.business.ISiteBusinessLocal;
import com.fengniu.ejb.business.ISiteBusinessRemote;
import com.fengniu.ejb.dao.CategoryDaoLocal;
import com.fengniu.ejb.dao.ContentDaoLocal;
import com.fengniu.ejb.dao.CouponDaoLocal;
import com.fengniu.ejb.dao.DeltaDaoLocal;
import com.fengniu.ejb.dao.SiteDaoLocal;
import com.fengniu.ejb.dao.UserDaoLocal;
import com.fengniu.ejb.dao.util.IEJBConstants;
import com.fengniu.ejb.entity.Category;
import com.fengniu.ejb.entity.Content;
import com.fengniu.ejb.entity.DeltaRelation;
import com.fengniu.ejb.entity.Site;
import com.fengniu.ejb.entity.Site2Category;
import com.fengniu.ejb.entity.Site2Content;
import com.fengniu.ejb.entity.Site2Site;
import com.fengniu.ejb.entity.User;
import com.fengniu.ejb.entity.User2Site;
import com.tianbing.adlottery.global.IConstants;

@Stateless
@LocalBinding(jndiBinding = IEJBConstants.SiteBusinessLocalJndiName)
@RemoteBinding(jndiBinding = IEJBConstants.SiteBusinessRemoteJndiName)
public class SiteBusinessImpl implements ISiteBusinessLocal, ISiteBusinessRemote {
	@EJB(name = IEJBConstants.UserDaoLocalJndiName)
	private UserDaoLocal userDao;

	@EJB(name = IEJBConstants.SiteDaoLocalJndiName)
	private SiteDaoLocal siteDao;

	@EJB(name = IEJBConstants.ContentDaoLocalJndiName)
	private ContentDaoLocal contentDao;

	@EJB(name = IEJBConstants.CouponDaoLocalJndiName)
	private CouponDaoLocal couponDao;

	@EJB(name = IEJBConstants.CategoryDaoLocalJndiName)
	private CategoryDaoLocal categoryDao;

	@EJB(name = IEJBConstants.DeltaDaoLocalJndiName)
	private DeltaDaoLocal deltaDao;

	public void setStorePositionCategory(long siteSysId, String categoryId) {
		Site2Category s2g = findStorePositionCategory(siteSysId);

		Site site = siteDao.findSiteBySysId(siteSysId);
		Category category = categoryDao.findCategoryByCategoryId(categoryId);
		if (site != null && category != null) {
			if (s2g == null) {
				s2g = new Site2Category();
				s2g.setSite(site);
				s2g.setRelationId(IConstants.RelationID.S2G_IS_MEMBER_OF.getId());
			}
			s2g.setCategory(category);

			siteDao.saveSite2Category(s2g);
		}
	}

	public Site2Category findStorePositionCategory(long siteSysId) {
		Integer[] relationIds = { IConstants.RelationID.S2G_IS_MEMBER_OF.getId() };
		List<Site2Category> s2gs = siteDao.getListSite2CategoryBy(siteSysId, relationIds, -1, null, null, 0, 100, null);
		if (s2gs != null && s2gs.size() > 0) {
			for (int i = 0; i < s2gs.size(); i++) {
				Site2Category s2g = s2gs.get(i);
				// only one leaf category for store position
				List childCats = categoryDao.getListChildCategoryBy(s2g.getCategory().getCategoryId(), 0, 1, null);
				if (childCats == null || childCats.size() == 0) {
					return s2g;
				}
			}
		}
		return null;
	}

	public List<Site2Content> getListSitePostMessage(long siteSysId, int pgno, int pgsize) {
		Integer[] relationIds = { IConstants.RelationID.S2C_IS_POSTEE_OF.getId() };
		Integer[] contentTypeIds = { IConstants.Type.CONTENT_MESSAGE.getId() };
		List<Site2Content> result = siteDao.getListSite2ContentBy(siteSysId, relationIds, -1, null, contentTypeIds,
				null, null, pgno, pgsize, null);
		return result;
	}

	public Site2Site addHordeRecommendStore(long hordeSiteSysId, long storeSiteSysId) {
		Site2Site result = null;
		Site horde = siteDao.findSiteBySysId(hordeSiteSysId);
		Site store = siteDao.findSiteBySysId(storeSiteSysId);
		if (horde != null && store != null) {
			Integer[] relationIds = { IConstants.RelationID.S2S_IS_RECOMMENDER_OF.getId() };

			List<Site2Site> s2ss = siteDao.getListSite2SiteBy(hordeSiteSysId, relationIds, storeSiteSysId, null, 0, 1,
					null);
			if (s2ss == null || s2ss.size() == 0) {
				Site2Site s2s = new Site2Site();
				s2s.setSite(horde);
				s2s.setRelationId(IConstants.RelationID.S2S_IS_RECOMMENDER_OF.getId());
				s2s.setSite2(store);
				result = siteDao.saveSite2Site(s2s);
			}
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	public Map<String, Object> getHordeRecommendStores(long hordeSiteSysId, long storeSiteSysId, int pgno, int pgsize) {
		Map<String, Object> result = new HashMap<String, Object>();
		Integer[] relationIds = { IConstants.RelationID.S2S_IS_RECOMMENDER_OF.getId() };

		List<Site2Site> site2SiteList = siteDao.getListSite2SiteBy(hordeSiteSysId, relationIds, storeSiteSysId, null,
				pgno, pgsize, null);
		long totalCount = siteDao.getCountSite2SiteBy(hordeSiteSysId, relationIds, storeSiteSysId, null);

		result.put("site2SiteList", site2SiteList);
		result.put("totalCount", new Long(totalCount));
		return result;
	}

	public Site2Content saveUserServedStoreCoupon(long userSysId, long servedSiteSysId, Content content) {
		Site2Content result = null;
		User user = userDao.findUserBySysId(userSysId);
		Site site = siteDao.findSiteBySysId(servedSiteSysId);
		if (user != null && site != null) {
			User2Site u2s = userDao.findUser2SiteBy(userSysId, IConstants.RelationID.U2S_IS_SERVANT_OF.getId(),
					servedSiteSysId);
			if (u2s != null) {
				// the user is servant of the store
				if (content.getTypeId()!=null && content.getTypeId().compareTo(IConstants.Type.CONTENT_COUPON.getId()) == 0) {
					Content c = contentDao.saveContent(content);

					result = siteDao.findSite2ContentBy(servedSiteSysId, IConstants.RelationID.S2C_IS_OWNER_OF.getId(),
							c.getSysId());
					if (result == null) {
						result = new Site2Content();
						result.setSite(site);
						result.setRelationId(IConstants.RelationID.S2C_IS_OWNER_OF.getId());
						result.setContent(c);
						result = siteDao.saveSite2Content(result);
					}
				}
			}
		}
		return result;
	}

	public List<Category> getSiteLongestCategoryTrail(long siteSysId, String limitedTopCategoryId) {
		List<Category> result = null;
		// get site's cateogry trail
		List<List<Category>> trails = this.getSiteCategoryTrails(siteSysId, limitedTopCategoryId);
		if (trails != null && trails.size() > 0) {
			for (List<Category> cats : trails) {
				if (result == null || result.size() < cats.size()) {
					result = cats;
				}
			}
		}
		return result;
	}

	public List<List<Category>> getSiteCategoryTrails(long siteSysId, String limitedTopCategoryId) {
		List<List<Category>> storePostionCategoryTrails = new ArrayList<List<Category>>(0);
		Integer[] relationIds = { IConstants.RelationID.S2G_IS_MEMBER_OF.getId() };
		List<Site2Category> s2gs = siteDao.getListSite2CategoryBy(siteSysId, relationIds, -1, null, null, 0, 100, null);
		if (s2gs != null && s2gs.size() > 0) {
			for (int i = 0; i < s2gs.size(); i++) {
				Site2Category s2gi = s2gs.get(i);
				List<Category> storePostionCategoryTrail = categoryDao.getListCategoryPrimaryTrailBy(s2gi.getCategory()
						.getCategoryId());
				if (storePostionCategoryTrail != null && storePostionCategoryTrail.size() > 0) {
					Category topCat = storePostionCategoryTrail.get(0);
					if (limitedTopCategoryId == null || limitedTopCategoryId.trim() == "") {
						storePostionCategoryTrails.add(storePostionCategoryTrail);
					} else if (topCat.getCategoryId() != null && topCat.getCategoryId().equals(limitedTopCategoryId)) {
						storePostionCategoryTrails.add(storePostionCategoryTrail);
					}
				}
			}
		}
		return storePostionCategoryTrails;
	}

	public List<Site2Site> getSitePageSections(long siteSysId) {
		Integer[] relationIds = { IConstants.RelationID.S2S_IS_PAGE_SECTION_OF.getId() };
		return siteDao.getListSite2SiteBy(siteSysId, relationIds, siteSysId, null, 0, 10, null);
	}

	public Site2Site findSitePageSection(long siteSysId, String pageSectionName) {
		Integer[] relationIds = { IConstants.RelationID.S2S_IS_PAGE_SECTION_OF.getId() };

		List<Site2Site> s2sList = siteDao.getListSite2SiteBy(siteSysId, relationIds, siteSysId, null, 0, 10, null);
		if (s2sList != null && s2sList.size() > 0) {
			for (int i = 0; i < s2sList.size(); i++) {
				Site2Site s2s = s2sList.get(i);
				if (s2s.getName().equals(pageSectionName)) {
					return s2s;
				}
			}
		}
		return null;
	}

	public Site2Site saveSitePageSection(long siteSysId, String sectionName, String longDesc) {
		Site site = siteDao.findSiteBySysId(siteSysId);
		if (site != null) {
			Site2Site pageSection = this.findSitePageSection(siteSysId, sectionName);
			if (pageSection == null) {
				pageSection = new Site2Site();
			}
			pageSection.setSite(site);
			pageSection.setRelationId(IConstants.RelationID.S2S_IS_PAGE_SECTION_OF.getId());
			pageSection.setSite2(site);
			pageSection.setName(sectionName);
			pageSection.setLongDesc(longDesc);
			return siteDao.saveSite2Site(pageSection);
		}
		return null;
	}

	public DeltaRelation addHordeRecommendStoreCoupon(long hordeSysId, long site2ContentSysId) {
		DeltaRelation result = null;
		Site site = siteDao.findSiteBySysId(hordeSysId);
		Site2Content site2Content = siteDao.findSite2ContentBy(site2ContentSysId);
		if (site != null && site2Content != null) {
			Integer relationId = IConstants.RelationID.S2SC_IS_RECOMMENDER_OF.getId();

			List<DeltaRelation> s2scList = deltaDao.getListDeltaRelation(hordeSysId, Site.class.getName(), relationId,
					site2ContentSysId, Site2Content.class.getName(), 0, 1);
			if (s2scList == null || s2scList.size() == 0) {
				DeltaRelation delta = new DeltaRelation();
				delta.setSite(site);
				delta.setRelationId(relationId);
				delta.setSite2Content2(site2Content);
				result = deltaDao.save(delta);
			}
		}
		return result;
	}

	public DeltaRelation addHordeRecommendStoreProduct(long hordeSysId, long site2ContentSysId) {
		DeltaRelation result = null;
		Site site = siteDao.findSiteBySysId(hordeSysId);
		Site2Content site2Content = siteDao.findSite2ContentBy(site2ContentSysId);
		if (site != null && site2Content != null) {
			Integer relationId = IConstants.RelationID.S2SC_IS_RECOMMENDER_OF.getId();

			List<DeltaRelation> s2scList = deltaDao.getListDeltaRelation(hordeSysId, Site.class.getName(), relationId,
					site2ContentSysId, Site2Content.class.getName(), 0, 1);
			if (s2scList == null || s2scList.size() == 0) {
				DeltaRelation delta = new DeltaRelation();
				delta.setSite(site);
				delta.setRelationId(relationId);
				delta.setSite2Content2(site2Content);
				result = deltaDao.save(delta);
			}
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	public Map<String, Object> getHordeRecommendStoreProducts(long hordeSiteSysId, long site2ContentSysId, int pgno,
			int pgsize) {
		Map<String, Object> result = new HashMap<String, Object>();

		Integer[] relationIds = { IConstants.RelationID.S2SC_IS_RECOMMENDER_OF.getId() };
		Integer[] statusIds = {};
		Integer[] contentTypeIds = { IConstants.Type.CONTENT_PRODUCT.getId() };

		List<DeltaRelation> horde2StoreProductList = deltaDao.getListSite2SiteContent2(hordeSiteSysId, relationIds,
				site2ContentSysId, contentTypeIds, pgno, pgsize);
		long totalCount = deltaDao.getCountSite2SiteContent2(hordeSiteSysId, relationIds, site2ContentSysId,
				contentTypeIds);
		result.put("site2StoreProductList", horde2StoreProductList);
		result.put("totalCount", new Long(totalCount));
		return result;
	}

	@SuppressWarnings("unchecked")
	public Map<String, Object> getHordeRecommendStoreCoupons(long hordeSiteSysId, long site2ContentSysId, int pgno,
			int pgsize) {
		Map<String, Object> result = new HashMap<String, Object>();

		Integer[] relationIds = { IConstants.RelationID.S2SC_IS_RECOMMENDER_OF.getId() };
		Integer[] statusIds = {};
		Integer[] contentTypeIds = { IConstants.Type.CONTENT_COUPON.getId() };

		List<DeltaRelation> horde2StoreProductList = deltaDao.getListSite2SiteContent2(hordeSiteSysId, relationIds,
				site2ContentSysId, contentTypeIds, pgno, pgsize);
		long totalCount = deltaDao.getCountSite2SiteContent2(hordeSiteSysId, relationIds, site2ContentSysId,
				contentTypeIds);
		result.put("site2StoreCouponList", horde2StoreProductList);
		result.put("totalCount", new Long(totalCount));
		return result;
	}

	public Site2Content addStoreSellProduct(long contentSysId, long storeSiteSysId) {
		Site2Content result = null;
		Site site = siteDao.findSiteBySysId(storeSiteSysId);
		Content content = contentDao.findContentBySysId(contentSysId);
		Integer[] relationIds = { IConstants.RelationID.S2C_IS_SELLER_OF.getId() };
		List<Site2Content> s2cs = siteDao.getListSite2ContentBy(storeSiteSysId, relationIds, contentSysId, null, null,
				null, null, 0, 1, null);
		if (s2cs == null || s2cs.size() == 0) {
			Site2Content s2c = new Site2Content();
			s2c.setSite(site);
			s2c.setRelationId(IConstants.RelationID.S2C_IS_SELLER_OF.getId());
			s2c.setContent(content);
			result = siteDao.saveSite2Content(s2c);
		}
		return result;
	}

	public Site2Content findStoreSellProduct(long contentSysId, long storeSiteSysId) {
		Site2Content result = null;
		Integer[] relationIds = { IConstants.RelationID.S2C_IS_SELLER_OF.getId() };
		List<Site2Content> s2cs = siteDao.getListSite2ContentBy(storeSiteSysId, relationIds, contentSysId, null, null,
				null, null, 0, 1, null);
		if (s2cs != null && s2cs.size() > 0) {
			result = s2cs.get(0);
		}
		return result;
	}

	public Map<String, Object> getStoreSellProducts(long contentSysId, long siteSysId, String siteCategoryId, int pgno,
			int pgsize) {
		Map<String, Object> result = new HashMap<String, Object>();
		Integer[] relationIds = { IConstants.RelationID.S2C_IS_SELLER_OF.getId() };
		List store2ContentList;
		Long totalCount;
		if (siteCategoryId != null) {
			Integer[] site2CategoryRelationIds = { IConstants.RelationID.S2G_IS_MEMBER_OF.getId() };
			store2ContentList = siteDao.getListSite2ContentBy(siteSysId, relationIds, contentSysId, null, null,
					site2CategoryRelationIds, siteCategoryId, pgno, pgsize, null);
			totalCount = siteDao.getCountSite2ContentBy(siteSysId, relationIds, contentSysId, null, null,
					site2CategoryRelationIds, siteCategoryId);
		} else {
			store2ContentList = siteDao.getListSite2ContentBy(siteSysId, relationIds, contentSysId, null, null, null,
					null, pgno, pgsize, null);
			totalCount = siteDao.getCountSite2ContentBy(siteSysId, relationIds, contentSysId, null, null, null, null);
		}

		result.put("site2ContentList", store2ContentList);
		result.put("totalCount", totalCount);
		return result;
	}

	public Site2Site updateHordeRecommendStore(long hordeServantUserSysId, Site2Site horde2Store) {
		Site2Site result = null;
		if (horde2Store != null) {
			// check the coming parameters are fine
			User user = userDao.findUserBySysId(hordeServantUserSysId);
			Site horde = horde2Store.getSite();
			Site store = horde2Store.getSite2();
			if (user != null && horde != null && store != null
					&& horde2Store.getRelationId().compareTo(IConstants.RelationID.S2S_IS_RECOMMENDER_OF.getId()) == 0) {
				User2Site userManagedHorde = userDao.findUser2SiteBy(user.getSysId(),
						IConstants.RelationID.U2S_IS_OWNER_OF.getId(), horde.getSysId());
				if (userManagedHorde != null) {
					// user is the horde owner,so we save horde 2 store
					result = siteDao.saveSite2Site(horde2Store);
				}
			}
		}
		return result;
	}

	public DeltaRelation updateHordeRecommendStoreCoupon(long hordeServantUserSysId, DeltaRelation horde2StoreCoupon) {
		DeltaRelation result = null;
		if (horde2StoreCoupon != null) {
			// check the coming parameters are fine
			User user = userDao.findUserBySysId(hordeServantUserSysId);
			Site horde = horde2StoreCoupon.getSite();
			Site2Content store2Coupon = horde2StoreCoupon.getSite2Content2();
			if (user != null
					&& horde != null
					&& store2Coupon != null
					&& store2Coupon.getContent().getTypeId().compareTo(IConstants.Type.CONTENT_COUPON.getId()) == 0
					&& horde2StoreCoupon.getRelationId()
							.compareTo(IConstants.RelationID.S2SC_IS_RECOMMENDER_OF.getId()) == 0) {
				User2Site userManagedHorde = userDao.findUser2SiteBy(user.getSysId(),
						IConstants.RelationID.U2S_IS_OWNER_OF.getId(), horde.getSysId());
				if (userManagedHorde != null) {
					// user is the horde owner,so we save horde 2 store
					result = deltaDao.save(horde2StoreCoupon);
				}
			}
		}
		return result;
	}

	public DeltaRelation updateHordeRecommendStoreProduct(long hordeServantUserSysId, DeltaRelation horde2StoreProduct) {
		DeltaRelation result = null;
		if (horde2StoreProduct != null) {
			// check the coming parameters are fine
			User user = userDao.findUserBySysId(hordeServantUserSysId);
			Site horde = horde2StoreProduct.getSite();
			Site2Content store2Product = horde2StoreProduct.getSite2Content2();
			if (user != null
					&& horde != null
					&& store2Product != null
					&& store2Product.getContent().getTypeId().compareTo(IConstants.Type.CONTENT_PRODUCT.getId()) == 0
					&& horde2StoreProduct.getRelationId().compareTo(
							IConstants.RelationID.S2SC_IS_RECOMMENDER_OF.getId()) == 0) {
				User2Site userManagedHorde = userDao.findUser2SiteBy(user.getSysId(),
						IConstants.RelationID.U2S_IS_OWNER_OF.getId(), horde.getSysId());
				if (userManagedHorde != null) {
					// user is the horde owner,so we save horde 2 store
					result = deltaDao.save(horde2StoreProduct);
				}
			}
		}
		return result;
	}

	public Map getHotWebSites(String categoryId, int pgno, int pgsize) {
		Map result = new HashMap();
		return result;
	}

	public void rankingSite(long siteSysId, int maxCategoryMember) {
		this.rankingSite(siteSysId, IConstants.CategoryID.AREA_TOP.getId(), maxCategoryMember);
		this.rankingSite(siteSysId, IConstants.CategoryID.BUSINESS_TOP.getId(), maxCategoryMember);
	}

	private void rankingSite(long siteSysId, String limitedTopCategoryId, int maxCategoryMember) {
		Site site = siteDao.findSiteBySysId(siteSysId);
		if (site != null) {
			List<Category> categoryList = this.getSiteLongestCategoryTrail(siteSysId, limitedTopCategoryId);
			Integer[] relationIds = { IConstants.RelationID.S2G_IS_MEMBER_OF.getId() };
			Integer[] siteTypeIds = { site.getTypeId() };
			if (categoryList != null && categoryList.size() > 0) {
				for (Category category : categoryList) {
					//1. we get the maxCategoryMember-nth site member of the category 
					List<Site2Category> nthMembers = siteDao.getListSite2CategoryBy(-1, relationIds, category
							.getSysId(), null, siteTypeIds, maxCategoryMember - 1, 1, null);
					List<Site2Category> theSite2CategoryList = null;
					if (nthMembers != null && nthMembers.size() > 0) {
						Site2Category nthMember = nthMembers.get(0);
						if (nthMember.getSite().getIntegral() != null
								&& nthMember.getSite().getIntegral().compareTo(
										site.getIntegral() == null ? 0 : site.getIntegral()) < 0) {
							// check whether the site has been the category's member
							theSite2CategoryList = siteDao.getListSite2CategoryBy(site.getSysId(), relationIds,
									category.getSysId(), null, siteTypeIds, 0, 1, null);
						}
					} else {
						theSite2CategoryList = siteDao.getListSite2CategoryBy(site.getSysId(), relationIds, category
								.getSysId(), null, siteTypeIds, 0, 1, null);
					}
					if (theSite2CategoryList == null || theSite2CategoryList.size() == 0) {
						Site2Category theSite2Category = new Site2Category();
						theSite2Category.setSite(site);
						theSite2Category.setRelationId(IConstants.RelationID.S2G_IS_MEMBER_OF.getId());
						theSite2Category.setCategory(category);
						siteDao.saveSite2Category(theSite2Category);
					}
				}
			}
			site.setLastRankedDate(new Date());
			siteDao.saveSite(site);
		}
	}

	public void addSiteAsCategoryMember(long siteSysId, String categoryId) {
		Site site = siteDao.findSiteBySysId(siteSysId);
		Category g = categoryDao.findCategoryByCategoryId(categoryId);
		if (site != null && g != null) {
			Site2Category s2g = siteDao.findSite2CategoryBy(siteSysId, IConstants.RelationID.C2G_IS_MEMBER_OF.getId(),
					g.getSysId());
			if (s2g == null) {
				s2g = new Site2Category();
				s2g.setSite(site);
				s2g.setRelationId(IConstants.RelationID.C2G_IS_MEMBER_OF.getId());
				s2g.setCategory(g);
				siteDao.saveSite2Category(s2g);
			} else if (s2g.getStatus() == null
					|| s2g.getStatus().compareTo(IConstants.Status.IS_APPROVE_SUCC.getId()) != 0) {
				s2g.setStatus(IConstants.Status.IS_APPROVE_SUCC.getId());
				siteDao.saveSite2Category(s2g);
			}
		}
	}

	public void deleteSiteFromCategoryMember(long siteSysId, String categoryId) {
		Site site = siteDao.findSiteBySysId(siteSysId);
		Category g = categoryDao.findCategoryByCategoryId(categoryId);
		if (site != null && g != null) {
			Site2Category s2g = siteDao.findSite2CategoryBy(siteSysId, IConstants.RelationID.C2G_IS_MEMBER_OF.getId(),
					g.getSysId());
			if (s2g != null) {
				s2g.setStatus(IConstants.Status.IS_APPROVE_FAIL.getId());
				siteDao.saveSite2Category(s2g);
			}

		}
	}

}
